#include <bits/stdc++.h>
using namespace std;

const int MAXN = 3000 + 5;
struct Node {
  int u, v, w;
  bool operator<(const Node &t) const { return w > t.w; }
};

std::priority_queue<Node> pq;
int x[MAXN], y[MAXN];

int d(int i, int j) { return abs(x[i] - x[j]) + abs(y[i] - y[j]); }

struct UnionFind {
  int f[MAXN];

  void init(int n) {
    for (int i = 1; i <= n; ++i)
      f[i] = i;
  }

  int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }

  void merge(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    f[x] = y;
  }
};

int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  UnionFind uf;

  for (int i = 1; i <= n; ++i)
    scanf("%d%d", x + i, y + i);
  for (int i = 1; i <= n; ++i)
    for (int j = i + 1; j <= n; ++j) {
      pq.push({i, j, d(i, j)});
    }

  uf.init(n);

  while (q--) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      ++n;
      scanf("%d%d", x + n, y + n);
      for (int i = 1; i <= n - 1; ++i)
        pq.push({i, n, d(i, n)});
      uf.f[n] = n;
    } else if (op == 2) {

      while (!pq.empty() && uf.find(pq.top().u) == uf.find(pq.top().v))
        pq.pop();
      if (pq.empty()) {
        puts("-1");
        continue;
      }
      int k = pq.top().w;
      printf("%d\n", k);
      while (!pq.empty() && pq.top().w == k) {
        uf.merge(pq.top().u, pq.top().v);
        pq.pop();
      }
    } else if (op == 3) {
      int a, b;
      scanf("%d%d", &a, &b);
      puts(uf.find(a) == uf.find(b) ? "Yes" : "No");
    }
  }
  return 0;
}